﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../impl/head.h"
#include "threads_impl.h"

/////////////////////////////////////////////////////////////////////////////////////////
// 
namespace xos_box
{
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static threads_impl::POOL * pool_ptr = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    threads_impl::threads_impl()
    {
        init_data();
    }

    threads_impl::~threads_impl()
    {
        term();
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int threads_impl::get_addr( POOL *** pppPool, LIST *** pppList )
    {
        int ret = 0;
        if( pppPool )
        {
            *pppPool = &pool_ptr;
        }
        if( pppList )
        {
            *pppList = 0;
        }
        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 
    // nNum = 0, means cpu core num
    // if not set, default is 0
    // 
    int threads_impl::set_max_thread_num( int nNum )
    {
        int ret = 0;

        m_nMaxThreadNum = nNum;

        if( ( 0 == ret ) && ( nNum <= 0 ) )
        {
            m_nMaxThreadNum = get_cpu_num();
        }

        return ret;
    }

    int threads_impl::notify( xos_box::i_msg *& pMsg )
    {
        int ret = 0;

        xos_box::i_callback * pThread = 0;
        int nTaskNum = 99999999;

        if( 0 == ret )
        {
            xos_box::i_callback * pT = 0;
            for( m_pThreadList->reset(); ( pT = ( xos_box::i_callback * )m_pThreadList->next() ); )
            {
                int num = pT->size();
                if( nTaskNum > num )
                {
                    nTaskNum = num;
                    pThread = pT;
                }
            }
        }

        if( ( 0 == ret ) && ( nTaskNum > m_nTaskNumForNewThread ) && ( m_pThreadList->size() < m_nMaxThreadNum ) )
        {
            xos_box::i_callback * pT = 0;
            mgr::get()->create( enumObj::BOX_OBJ_CALLBACK, ( void ** )&pT);
            m_pThreadList->push_back( pT );
            pThread = pT;
        }

        if( 0 == ret )
        {
            pThread->notify( pMsg );
        }

        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int threads_impl::get_cpu_num()
    {
        int ret = 0;

        ret = mgr::misc()->get_cpu_num();

        return ret;
    }

    int threads_impl::init_data()
    {
        int ret = 0;

        m_nTaskNumForNewThread = 3;
        m_nMaxThreadNum = 0;
        m_pThreadList = 0;

        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int threads_impl::init()
    {
        int ret = 0;

        if( 0 == ret )
        {
            ret = mgr::get()->create( enumObj::BOX_OBJ_LIST, ( void ** )&m_pThreadList );
        }

        if( ( 0 == ret ) && ( m_nMaxThreadNum <= 0 ) )
        {
            m_nMaxThreadNum = get_cpu_num();
        }

        return ret;
    }

    int threads_impl::term()
    {
        int ret = 0;

        xos_stl::release_interface( m_pThreadList );

        init_data();

        return ret;
    }

} // xos
